<?php
require_once "funct.getForms.php";
require_once "funct.getFiles.php";
require_once "class.rglDocGen.php";

class rglForm {
	public $form = '';
	public $descr = '';
	public $regoleDir = '';
	public $aFiles = array();
	public $aCampiForm = array();
	public $aCampiFormDef = array();
	public $aCampiDB = array();
	public $aCampiDBDef = array();
	public $oDocGen = null;
	public $errno = 0;
	public $error = '';
	
	public function __construct($form) {
		global $objDB, $objSess;
		$this->form = $form;
		if (!$aForm = getForms($form)) return $this->setErr(10,"form $form invalid");
		$this->descr = $aForm['descr'];
		$this->regoleDir = $aForm['dir'];
		$this->aCampiForm = $_REQUEST;
		$this->aFiles = array();
		foreach ($aForm['files'] as $file => $aX) {
			if ($aFile = getFiles($file)) {
				$this->aFiles[$file] = $aFile;
				$this->aFiles[$file]['alias'] = $aX['alias'];
				$aDef = getDefCampi($file);
				foreach($aDef as $campoY => $aY) {
					$this->aCampiDBDef[$aX['alias']."_".$campoY] = $aDef[$campoY];
				}
			}
		}
		$sql_sel = "SELECT c.*" .
				" FROM rgl_campi_form c " .
				" WHERE c.cod_form = '".$this->form."'".
				" ORDER BY c.riga,c.posiz ";
		$objDB->query($sql_sel,'selRecCampi');
		while($acX = $objDB->fetch('selRecCampi')) {
			$this->aCampiFormDef[$acX['riga']][$acX['posiz']] = $acX;
		}
	}
	
	private function setErr($err=0,$des='') {
		$this->errno = $err;
		$this->error = $des;
		return ($err==0);
	}
	
	private function eseguiRegole($regola) {
		$scriptName = $this->form."_".$regola.".php";
		$regolaStdPath = RGL_FS_WEB_ROOT."/app".$this->regoleDir."/_reg/$scriptName";
		//dbg_("regolaStdPath=$regolaStdPath");
		$regolaPerPath = RGL_FS_WEB_ROOT."/pers/regole/".$this->regoleDir."/$scriptName";
		//dbg_("regolaPerPath=$regolaPerPath");
		$sRet = '';
		if (file_exists($regolaStdPath)) {
			$script = file_get_contents($regolaStdPath);
			$posFun = strpos($script,'function ');
			$posPar = strpos($script,'{',$posFun);
			if ($posFun !== false && $posPar !== false) {
				$nomeFunz = uniqid($regola);
				$script = "function $nomeFunz(&\$aCampiForm,&\$aCampiDB)".substr($script,$posPar);
				eval($script);
				$sRet .= $nomeFunz($this->aCampiForm,$this->aCampiDB);
			}
		}
		if (file_exists($regolaPerPath)) {
			$script = file_get_contents($regolaPerPath);
			$posFun = strpos($script,'function ');
			$posPar = strpos($script,'{',$posFun);
			if ($posFun !== false && $posPar !== false) {
				$nomeFunz = uniqid($regola);
				$script = "function $nomeFunz(&\$aCampiForm,&\$aCampiDB)".substr($script,$posPar);
				eval($script);
				$sRet .= $nomeFunz($this->aCampiForm,$this->aCampiDB);
			}
		}
		return $sRet;
	}
	
	public function setDef() {
		$this->eseguiRegole("setdef");
		return '';
	}
	
	public function preForm() {
		$this->eseguiRegole("preform");
		return '';
	}
	
	public function db2form() {
		foreach($this->aCampiFormDef as $riga => $aRigaX) {
			$colDisp = 20;
			foreach($aRigaX as $posX => $file) {
				if ($colDisp <= 0) break;
				$colDisp -= $file['label_size']+$file['campo_size'];
				$campoX = $file['campo'];
				switch($file['campo_type']) {
					case 'data':
						$this->aCampiForm[$campoX] = YMD2DMY($this->aCampiDB[$campoX]);
						break;
					case 'numero':
						$this->aCampiForm[$campoX] = num2str($this->aCampiDB[$campoX],$file['campo_dec']);
						break;
					case 'si/no':
						$this->aCampiForm[$campoX] = ($this->aCampiDB[$campoX]=='S')?'S':'N';
						break;
					default:
						$this->aCampiForm[$campoX] = $this->aCampiDB[$campoX];
						break;
				}
			}
		}
		$this->eseguiRegole("db2form");
		return '';
	}
		
	public function getHtmlCampiView() {
		global $objDB;
		$sHtml = '';
		foreach($this->aCampiFormDef as $riga => $aRigaX) {
			$sHtml .= "<tr>\n";
			$colDisp = 20;
			foreach($aRigaX as $posX => $aCX) {
				if ($colDisp > 0) {
					if ($aCX['label_size']>0) {
						$cols = ($aCX['label_size']<$colDisp)?$aCX['label_size']:$colDisp;
						$sHtml .= $this->getTdLabel($cols, $aCX);
						$colDisp -= $cols;
					}
					if ($aCX['campo_size']>0) {
						$cols = ($aCX['campo_size']<$colDisp)?$aCX['campo_size']:$colDisp;
						$sHtml .= $this->getTdView($cols, $aCX);
						$colDisp -= $cols;
					}
				}
			} 
			if ($colDisp>0) {
				$sHtml .= "<td class='txt1' colspan='$colDisp'>&nbsp;</td>\n";
			}
			$sHtml .= "</tr>\n";
		}
		return $sHtml;
	}
	
	
	private function getTdLabel($cols, $aCX) {
		$sStyle = '';
		switch ($aCX['campo_style']) {
			case 'b':
				$sStyle .= "font-weight:bold;";
				break;
			case 'i':
				$sStyle .= "font-style:italic;";
				break;
			case 'ib':
			case 'bi':
				$sStyle .= "font-weight:bold;font-style:italic;";
				break;
		}
		$sHtml = "<td class='lab1' colspan='$cols' style=\"$sStyle\">";
		$sHtml .= $aCX['label']."</td>\n";
		return $sHtml;
	}
	
	private function getTdView($cols, $aCX) {
		$sStyle = '';
		switch ($aCX['campo_style']) {
			case 'b':
				$sStyle .= "font-weight:bold;";
				break;
			case 'i':
				$sStyle .= "font-style:italic;";
				break;
			case 'ib':
			case 'bi':
				$sStyle .= "font-weight:bold;font-style:italic;";
				break;
		}
		$size = $cols * 5;
		$sHtml = "<td class='txt1' colspan='$cols' style=\"$sStyle\">";
		switch ($aCX['campo_type']) {
			case 'nota':
				$sHtml .= getHtmlViewNote(rglVx($this->aCampiForm,$aCX['campo']));
				break;
			case 'bool':
				$sHtml .= (rglVx($this->aCampiForm,$aCX['campo']))?'Si\'':'No';
				break;
			case 'tabella':
				$sVal = rglVx($this->aCampiForm,$aCX['campo']);
				if ($sVal == '') {
					$sHtml .= "&nbsp;";
					break;
				}
				$this->loadVal($aCX);
				$sValX = rglVx($this->aCampiFormDef,$aCX['campo'],'aVal',$sVal);
				$sHtml .= $sVal;
				if ($sValX != '' && $sValX != $sVal) {
					$sHtml .= " - ".$sValX;
				}
				break;
			default:
				$sHtml .= rglVx($this->aCampiForm,$aCX['campo']);
				break;
		}
		$sHtml .= "</td>\n";
		return $sHtml;
	}
	
	public function getHtmlCampiForm() {
		global $objDB;
		$sHtml = '';
		foreach($this->aCampiFormDef as $riga => $aRigaX) {
			$sHtml .= "<tr>\n";
			$colDisp = 20;
			foreach($aRigaX as $posX => $aCX) {
				if ($colDisp > 0) {
					if ($aCX['label_size']>0) {
						$cols = ($aCX['label_size']<$colDisp)?$aCX['label_size']:$colDisp;
						$sHtml .= $this->getTdLabel($cols, $aCX);
						$colDisp -= $cols;
					}
					if ($aCX['campo_size']>0) {						
						$cols = ($aCX['campo_size']<$colDisp)?$aCX['campo_size']:$colDisp;
						$sHtml .= $this->getTdCampo($cols, $aCX);
						$colDisp -= $cols;
					}
				}
			} 
			if ($colDisp>0) {
				$sHtml .= "<td class='txt1' colspan='$colDisp'>&nbsp;</td>\n";
			}
			$sHtml .= "</tr>\n";
		}
		return $sHtml;
	}
	
	private function getTdCampo($cols, $aCX) {
		$size = $cols * 5;
		$sStyle = '';
		switch ($aCX['campo_style']) {
			case 'b':
				$sStyle .= "font-weight:bold;";
				break;
			case 'i':
				$sStyle .= "font-style:italic;";
				break;
			case 'ib':
			case 'bi':
				$sStyle .= "font-weight:bold;font-style:italic;";
				break;
		}
		$sHtml = "<td class='txt1' colspan='$cols' style=\"$sStyle\">";
		switch($aCX['campo_type']) {
			case 'data':
				$sHtml .= $this->getHtmlDate($aCX);
				break;
			case 'numero':
				$sHtml .= $this->getHtmlNum($aCX);
				break;
			case 'bool':
				$sHtml .= $this->getHtmlSN($aCX);
				break;
			case 'tabella':
				$sHtml .= $this->getHtmlSelect($aCX);
				break;
			case 'nota':
				$sHtml .= $this->getHtmlNota($aCX);
				break;
			default:
				$sHtml .= $this->getHtmlText($aCX);
				break;
		}		
		$sHtml .= "</td>\n";			
		return $sHtml;
	}
	
	private function getHtmlNota($aCX, $aOpt=array()) {
		$name = $aCX['campo'];
		$sStyle = "width:100%;";
		$sReadOnly = (isset($aOpt['readonly']))?' READONLY':'';
		$sClass = (isset($aOpt['class']))?$aOpt['class']:'inp1';
		$rows = intval(rglVx($aCX,"campo_dec"));
		$sVal = htmlentities(rglVx($this->aCampiForm,$name));
		$sHtml = "<textarea class=\"$sClass\" name=\"$name\" id=\"$name\" style=\"$sStyle\"" .
				" rows=\"$rows\" $sReadOnly>$sVal</textarea>\n";
		return $sHtml;
	}
	
	private function loadVal($aCX, $aOpt=array()) {
		global $objDB;
		$aT = explode('@',$aCX['campo_tab']);
		if (rglVx($aT,2)=='') return false;
		if (rglVx($aT,1)==0) $c1 = "chiave";
		else $c1 = "c".str_pad(rglVx($aT,1),2,'0',STR_PAD_LEFT);
		if (rglVx($aT,2)==0) $c2 = "chiave";
		else $c2 = "c".str_pad(rglVx($aT,2),2,'0',STR_PAD_LEFT);
		$sSql = "SELECT v.$c1,v.$c2 FROM rgl_tabelle_val v "
			." INNER JOIN rgl_tabelle t ON t.cod_tabella = '".addslashes($aT[0])."' "
			." AND t.id_tabella = v.id_tabella "
			." ORDER BY v.$c1";
		$objDB->query($sSql,'selValTab');
		$aVal = array(""=>_t("-- seleziona --"));
		while($acTab = $objDB->fetch('selValTab')) {
			$aVal[$acTab[$c1]] = $acTab[$c2];
		}
		$this->aCampiFormDef[$aCX['campo']]['aVal'] = $aVal;
		return true;
	}
	
	private function getHtmlSelect($aCX, $aOpt=array()) {
		$name = $aCX['campo'];
		$sOnChange = (isset($aOpt['onChange']))?' onChange="'.$aOpt['onChange'].'"':'';
		$style = (isset($aOpt['style']))?' style="'.$aOpt['style'].'"':'';
		$sHtml='<select class="inp1" id="'.$name.'" name="'.$name.'"'.$sOnChange.$style.'>';
		$sVal = rglVx($this->aCampiForm,$name);
		$this->loadVal($aCX, $aOpt);
		if (isset($this->aCampiFormDef[$name]['aVal'])) {
			foreach($this->aCampiFormDef[$name]['aVal'] as $vX => $dX) {
				$sel = ($sVal == $vX)?' selected':'';
				$sHtml .= '<option value="'.htmlentities($vX).'"'.$sel.'>'.htmlentities($dX).'</option>';
			}
		}
		$sHtml.='</select>'."\n";
		return $sHtml;
	}
	
	private function getHtmlText($aCX, $aOpt=array()) {
		$name = $aCX['campo'];
		$sStyle = "width:100%;";
		if (isset($aOpt['style'])) $sStyle .= $aOpt['style'];
		$sVal = htmlentities(rglVx($this->aCampiForm,$name));
		$sHtml = '<input type="text" class="inp1" name="'.$name.'" id="'.$name.'" value="'.$sVal.'" '.
			" style=\"$sStyle\" >\n";
		return $sHtml;
	}
	
	private function getHtmlNum($aCX, $aOpt=array()) {
		$name = $aCX['campo'];
		if (isset($aOpt['style'])) {
			$aOpt['style'] .= "text-align:right;";
		} else {
			$aOpt['style'] = "text-align:right;";
		}
		return $this->getHtmlText($aCX, $aOpt);
	}
	
	private function getHtmlRadio($aCX, $aOpt=array()) {
		$name = $aCX['campo'];
		$sVal = htmlentities(rglVx($this->aCampiForm,$name));
		$sHtml='';
		$sSep = (isset($aOpt['aCapo']) and $aOpt['aCapo'])?"<br>\n":"&nbsp;&nbsp;&nbsp;\n";
		$sOnClick = (isset($aOpt['onClick']) and $aOpt['onClick'])?" onClick=\"".$aOpt['onClick']."\"":"";
		$i = 1;
		foreach($aVal as $vX => $dX) {
			$chk = ($sVal == $vX)?' checked':'';
			$sHtml .= '<input type="radio" id="'.$name."_".$i.'" name="'.$name.'" value="'.htmlentities($vX)
				.'"'.$chk.$sOnClick.' class="inp1">&nbsp;'.htmlentities($dX).$sSep;
			$i++;
		}
		return $sHtml;
	}
	
	private function getHtmlSN($aCX, $aOpt=array()) {
		$name = $aCX['campo'];
		$sVal = rglVx($this->aCampiForm,$name);
		$sHtml='';
		$sSep = (isset($aOpt['aCapo']) and $aOpt['aCapo'])?"<br>\n":"&nbsp;&nbsp;&nbsp;\n";
		$sOnClick = (isset($aOpt['onClick']) and $aOpt['onClick'])?" onClick=\"".$aOpt['onClick']."\"":"";
		$chk = ($sVal)?' checked':'';
		$sHtml .= '<input type="radio" id="'.$name.'_1" name="'.$name.'" value="1"'
			.$chk.$sOnClick.' class="inp1">&nbsp;Si\''.$sSep;
		$chk = (!$sVal)?' checked':'';
		$sHtml .= '<input type="radio" id="'.$name.'_2" name="'.$name.'" value="0"'
			.$chk.$sOnClick.' class="inp1">&nbsp;No'.$sSep;
		return $sHtml;
	}
		
	private function getHtmlDate($aCX, $aOpt=array()) {
		$name = $aCX['campo'];
		$nomeForm = (isset($aOpt['nomeForm']))?$aOpt['nomeForm']:'frm1';
		$sReadOnly = (isset($aOpt['readonly']))?' READONLY':'';
		$sOnChange = (isset($aOpt['onChange']))?' onChange="'.$aOpt['onChange'].'" ':'';
		$sOpzSubm = ($sOnChange=='')?"":"submOrig=S&";
		$sMaxLen = '10';
		$sVal = htmlentities(rglVx($this->aCampiForm,$name));
		$sHtml = "<input type=\"text\" class=\"inp1\" name=\"$name\" id=\"$name\" value=\"$sVal\"".
			" size=\"8\" maxlength=\"10\" $sReadOnly $sOnChange>".
			"&nbsp;<img src='".RGL_URL_ROOT."/app/_img/calendario.png' " .
			"style='text-decoration:underline;cursor:pointer;'  onClick=\"apriCalend_$nomeForm$name();\" />\n";
		$sHtml .= "<script>";
		$sHtml .= "function apriCalend_$nomeForm$name() {\n" .
			"dtVal = encodeURIComponent(document.$nomeForm.$name.value);\n".
			"window.open('".RGL_URL_ROOT."/app/_com/calendario.php?$sOpzSubm" .
			"nome_form=$nomeForm&nome_campo=$name&dt='+dtVal+'&xsn=".XSN."'" .
			",'Calendario','top=200,left=100,width=290,height=240," .
			"resizable=yes,titlebar=no,location=no,location=no,menubar=no,toolbar=no');\n".		
				"}\n";
		$sHtml .= "</script>\n";
	return $sHtml;
	}
	
	public function setDocGen() {
		global $objDB;
						
		$sHtml = '';
		foreach($this->aCampiFormDef as $riga => $aRigaX) {
			$this->oDocGen->nuovaRiga();
			$colDisp = 20;
			foreach($aRigaX as $posX => $aCX) {
				if ($colDisp > 0) {
					if ($aCX['label_size']>0) {
						$cols = ($aCX['label_size']<$colDisp)?$aCX['label_size']:$colDisp;
						$this->setDocGenLabel($cols, $aCX);
						$colDisp -= $cols;
					}
					if ($aCX['campo_size']>0) {
						$cols = ($aCX['campo_size']<$colDisp)?$aCX['campo_size']:$colDisp;
						$this->setDocGenCampo($cols, $aCX);
						$colDisp -= $cols;
					}
				}
			} 
			if ($colDisp>0) {
				$this->setDocGenFiller($colDisp);
			}
		}		
		return true;
	}
	
	private function setDocGenLabel($cols, $aCX) {
		$sStyle = '';
		switch ($aCX['label_style']) {
			case 'b':
				$sStyle .= "font-weight:bold;";
				break;
			case 'i':
				$sStyle .= "font-style:italic;";
				break;
			case 'ib':
			case 'bi':
				$sStyle .= "font-weight:bold;font-style:italic;";
				break;
		}
		$aCol = array('cla'=>'txt1');
		$aCol['col'] = $cols*2;
		$aCol['alg'] = 'L';
		$aCol['txt'] = $aCX['label'];
		$this->oDocGen->setCol($aCol);
		return true;
	}
	
	private function setDocGenCampo($cols, $aCX) {
		$sStyle = '';
		switch ($aCX['campo_style']) {
			case 'b':
				$sStyle .= "font-weight:bold;";
				break;
			case 'i':
				$sStyle .= "font-style:italic;";
				break;
			case 'ib':
			case 'bi':
				$sStyle .= "font-weight:bold;font-style:italic;";
				break;
		}
		switch ($aCX['campo_type']) {
			case 'tabella':
				$sVal = rglVx($this->aCampiForm,$aCX['campo']);
				$this->loadVal($aCX);
				$sValX = rglVx($this->aCampiFormDef,$aCX['campo'],'aVal',$sVal);
				if ($sValX != '' && $sValX != $sVal) {
					$sVal .= " - ".$sValX;
				}
				break;
			default:
				$sVal = rglVx($this->aCampiForm,$aCX['campo']);
				break;
		}
		$aCol = array('cla'=>'txt1');
		$aCol['col'] = $cols*2;
		$aCol['alg'] = 'L';
		$aCol['txt'] = $sVal;
		$this->oDocGen->setCol($aCol);
		return true;
	}
	
	private function setDocGenFiller($cols) {
		$aCol = array('cla'=>'txt1');
		$aCol['col'] = $cols*2;
		$aCol['alg'] = 'L';
		$aCol['txt'] = "";
		$this->oDocGen->setCol($aCol);
		return true;
	}
	
	public function formCheck() {
		$msg = '';
		foreach($this->aCampiFormDef as $riga => $aRigaX) {
			$colDisp = 20;
			foreach($aRigaX as $posX => $aCX) {
				if ($colDisp <= 0) break;
				$colDisp -= $aCX['label_size']+$aCX['campo_size'];
				$campoX = $aCX['campo'];
				$campoZ = (($aCX['label']=='')?substr($campoX,2):$aCX['label'])." - ";
				if (trim($this->aCampiForm[$campoX])=='') {
					if ($aCX['campo_obb'] == 'S') {
						$msg .= $campoZ._t("campo obbligatorio")."<br/>";					
					}
				} else {
					switch($aCX['campo_type']) {
						case 'data':
							if (!str2date($this->aCampiForm[$campoX])) {
								$msg .= $campoZ._t("data errata")."<br>";
							}
							break;
						case 'numero':
							if (str2num($this->aCampiForm[$campoX])===false) {
								$msg .= $campoZ._t("non numerico")."<br>";
							}
							break;
						default:
							break;
					}
				}
			}
		}
		$msg .= $this->eseguiRegole("check");
		return $msg;
	}
	
	public function form2db() {
		foreach($this->aCampiFormDef as $riga => $aRigaX) {
			$colDisp = 20;
			foreach($aRigaX as $posX => $aCX) {
				if ($colDisp <= 0) break;
				$colDisp -= $aCX['label_size']+$aCX['campo_size'];
				$campoX = $aCX['campo'];
				if (!isset($this->aCampiForm[$campoX])) continue;
				switch($aCX['campo_type']) {
					case 'data':
						$this->aCampiDB[$campoX] = DMY2YMD($this->aCampiForm[$campoX]);
						break;
					case 'numero':
						$this->aCampiDB[$campoX] = str2num($this->aCampiForm[$campoX]);
						break;
					case 'si/no':
						$this->aCampiDB[$campoX] = ($this->aCampiForm[$campoX]=='S')?'S':'N';
						break;
					default:
						$this->aCampiDB[$campoX] = $this->aCampiForm[$campoX];
						break;
				}
			}
		}
		$this->eseguiRegole("form2db");
		return '';
	}
	
	public function getCampiSelect($alias='') {
		$sSql = '';
		foreach($this->aCampiDBDef as $campoX => $aDefX) {
			if ($alias != '' && $campoX[0] != $alias) continue;
			$campoZ = $campoX;
			$campoZ[1] = '.';
			$sSql .= "$campoZ AS $campoX, ";
		}
		return substr($sSql,0,-2);
	}
	
	public function getInsertDB($file) {
		$sSql = "INSERT INTO $file SET ";
		$alias = $this->aFiles[$file]['alias'];
		foreach($this->aCampiDB as $campoX => $valX) {
			if ($campoX[0] != $alias) continue;
			if (!isset($this->aCampiDBDef[$campoX])) continue;
			$aDefX = $this->aCampiDBDef[$campoX];
			if ($aDefX[2]=='auto_increment') continue;
			$sSql .= substr($campoX,2)." = '".addslashes($valX)."', ";
		}
		return substr($sSql,0,-2);
	}
	
	public function getUpdateDB($file) {
		$sSql = "UPDATE $file SET ";
		$alias = $this->aFiles[$file]['alias'];
		$aPK = explode(',',$this->aFiles[$file]['primary']);
		foreach($this->aCampiDB as $campoX => $valX) {
			if ($campoX[0] != $alias) continue;
			if (!isset($this->aCampiDBDef[$campoX])) continue;
			$aDefX = $this->aCampiDBDef[$campoX];
			if (in_array(substr($campoX,2),$aPK)) {
				continue;
			}
			$sSql .= substr($campoX,2)." = '".addslashes($valX)."', ";
		}
		$sSql = substr($sSql,0,-2)." WHERE ";
		foreach($aPK as $kX => $fieldX) {
			$sVal = rglVx($this->aCampiDB,$alias."_".$fieldX);
			$sSql .= $fieldX." = '".addslashes($sVal)."' AND ";
		}
		return substr($sSql,0,-5);
	}
	
} //fine classe